<cfsetting enablecfoutputonly="true">
	<cfswitch expression="#thisTag.executionMode#">
		<cfcase value="start">
			<!--- The id attribute is required. --->
			<cfparam name="attributes.id" type="string" default="">
			<!--- ensure the tag's required attributes are passed in --->
			
			<!--- href is required, it can be: http://whatever.com/...foo.cfm or foo.cfm --->
			<cfparam name="attributes.href" type="string" default="">
			
			<!--- ensure the tag's optional attributes are defaulted if not passed in --->
			
			<!--- 
			query string, should be passed in as key1=val1&key2=val2&key3=val3...linktext 
			it's best to do this so that you can switch from the 3 types of urls easily
			without having to reconfigure later on
			--->
			<cfparam name="attributes.qstring" type="string" default="">
			
			<!--- type can be: standard urls, SES, or Rewrite (Apache or IIS) --->
			<cfparam name="attributes.type" type="string" default="standard">
			
			<!--- 
			boolean value whether or not to display the key=value or key/value to remove
			the key from the string
			--->
			<cfparam name="attributes.showkeys" type="boolean" default="true">
			
			<!--- 
			if you rewrite a url and you want to add index.html or just simply add .html at
			the end of your urls, you would use this attribute			
			--->
			<cfparam name="attributes.extension" type="string" default="">
			
			<!--- this is the value that will be wrapped for hyperlinks	--->
			<cfparam name="attributes.value" type="string" default="">
			
			<!--- 
			if you're rewriting urls, you may want to name the file for example:
			index.cfm renamed to products or whatever makes sense for the link
			--->
			
			<!---  --->
			<cfparam name="attributes.rename" type="string" default="">
			<cfparam name="attributes.formatter" type="string" default="">
			<cfparam name="attributes.formatterMask" type="string" default="">
			<cfparam name="attributes.formatterType" type="string" default="">
			<cfparam name="attributes.formatterVersion" type="string" default="">
			<!--- assign the href to result --->
			<cfif StructKeyExists(caller,'root')>
				<cfset root = caller.root>
			<cfelse>
				<cfset root = caller>
			</cfif>
			<cfif NOT thisTag.hasEndTag>
				<cfthrow detail="End tag required" message="All coop tags require an end tag." errorcode="sos.tag.attributes">
			</cfif>
			<cfif attributes.id EQ ''>
				<cfthrow detail="Missing required attribute: 'id'" message="'id' attribute is required">
			</cfif>
			<!--- Test for the existence of the COOP framework. This will either be through a base COOP tag, or it is available in SOS --->
			<cfif NOT structKeyExists(root,"coop")>
				<cfthrow detail="Missing required COOP object on calling page.">
			</cfif>
			<!--- This segment is what interacts with the CoProcessor... It checks to see if the CoProcessor set any integrated or non-integrated attributes --->
			<cfscript>
			standardattributes = 'id,formatter,formatterMask,formatterType,formatterVersion,href,qstring,type,showKeys,extension,value,rename';
			attributes = root.coop.mergeAttributes(attributes,root);
			attributeList = root.coop.createAttributeList(attributes,standardAttributes,root);
		</cfscript>
			<cfif attributes.href EQ ''>
				<!--- I check for the href attribute here and not above because I want the coProcessor to be able to set attributes. --->
				<cfthrow message="Missing required attribute HREF on element '#attributes.id#'">
			</cfif>
			<cfset result = attributes.href />
			<!--- check for a querystring value and that it's not blank --->
			<cfif structkeyexists(attributes,'qstring') and attributes.qstring neq ''>
				<!--- check for boolean showkeys to determine if we're showing the keys or not, default false --->
				<cfif structkeyexists(attributes,'showkeys') and attributes.showkeys>
					<!--- check the type of url we're creating, default standard --->
					<cfswitch expression="#attributes.type#">
						<!--- example: index.cfm?key1=val1&key2=val2&key3=val3 --->
						<cfcase value="standard">
							<cfset result = result & '?' & attributes.qstring />
						</cfcase>
						<!--- example: index.cfm/key1/val1/key2/val2/key3/val3 --->
						<cfcase value="ses">
							<cfset result = result & '/' & rereplacenocase(attributes.qstring,'(\?)|(&)|(=)','/','all') />
						</cfcase>
						<!--- example: index/key1/val1/key2/val2/key3/val3 --->
						<cfcase value="rewrite">
							<cfif structkeyexists(attributes,'rename') and attributes.rename neq ''>
								<cfset result = attributes.rename />
							</cfif>
							<cfset result = rereplacenocase(result,'(.cfm)','','all') & '/' & rereplacenocase(attributes.qstring,'(\?)|(&)|(=)','/','all')>
						</cfcase>
					</cfswitch>
					<!--- run this condition if we are going to be hiding the keys --->
				<cfelse>
					<cfswitch expression="#attributes.type#">
						<!--- standard doesn't change, not sure if it's a good idea to hide the keys on this one --->
						<!--- example: index.cfm?key1=val1&key2=val2&key3=val3 --->
						<cfcase value="standard">
							<cfset result = result & '?' & attributes.qstring />
						</cfcase>
						<!--- example: index.cfm/val1/val2/val3 --->
						<cfcase value="ses">
							<cfset result = result & '/' & rereplacenocase(rereplacenocase(attributes.qstring,'([[:alnum:]\_\-]*=)','','all'),'(&)','/','all') />
						</cfcase>
						<!--- example: index/val1/val2/val3 --->
						<cfcase value="rewrite">
							<cfif structkeyexists(attributes,'rename') and attributes.rename neq ''>
								<cfset result = attributes.rename />
							</cfif>
							<cfset result = rereplacenocase(result,'(.cfm)','','all') & '/' & rereplacenocase(rereplacenocase(attributes.qstring,'([[:alnum:]\_\-]*=)','','all'),'(&)','/','all')>
						</cfcase>
					</cfswitch>
				</cfif>
			</cfif>
			<!--- example: index/val1/val2/val3.html or product/val1/val2/index.html --->
			<cfif structkeyexists(attributes,'extension') and attributes.extension neq ''>
				<cfset result = result & attributes.extension />
			</cfif>
		</cfcase>
		<cfcase value="end">
			<!--- This allows the link value to be set using the value attribute or the generatedContent --->
			<cfif attributes.value EQ ''>
				<cfset attributes.value = thisTag.generatedContent>
			</cfif>
			<cfif len(attributes.formatter)>
				<cfset attributes.value = root.coop._formatter(attributes.formatter,attributes.value,attributes)>
			</cfif>
			<cfif attributes.value EQ ''> 
				<cfoutput>  <!--- I wrapped this in a span so that we could append the extra attributes passed in... it is a core COOP feature --->
					<span#attributeList#>#result#</span>
				</cfoutput>  
			<cfelse>
				<cfoutput>  <!--- Add in nonstandard COOP attributes with the #attributeList# feature used below. --->
					<a href="#result#"#attributeList#>#attributes.value#</a>
				</cfoutput>  
			</cfif>
		<cfset thisTag.GeneratedContent = "" />
		</cfcase>
	</cfswitch>
<cfsetting enablecfoutputonly="false">